#CXXFLAGS += -Werror
ARFLAGS := rcs

ifdef ADDITIONALCXXFLAGS
	CXXFLAGS += $(ADDITIONALCXXFLAGS)
endif

ifdef ADDITIONALARFLAGS
	ARFLAGS += $(ADDITIONALARFLAGS)
endif

ifeq ($(TARGET), Release)
	CXXFLAGS += -O3

#	ifeq ($(CXX), g++)
#		CXXFLAGS += $(if $(GCC_MAJOR) >= 4 && $(GCC_MINOR) >= 5,-flto,)
#	endif
endif

ifeq ($(TARGET), Debug)
	CXXFLAGS += -ggdb
endif

ifeq ($(CXX), clang++)
#	CXXFLAGS += -Wno-unused-value -mfloat-abi=hard
endif

CXXFLAGS += $(INCLUDES)

OBJECTS=$(addsuffix .o, $(addprefix $(OBJDIR)$(TARGET)/, $(basename  $(SOURCES))))
OBJECTS:=$(OBJECTS) $(addsuffix .o, $(addprefix $(OBJDIR)$(TARGET)/, $(basename $(LEXERS))))
OBJECTS:=$(OBJECTS) $(addsuffix .o, $(addprefix $(OBJDIR)$(TARGET)/, $(basename $(PARSERS))))
ALLPARSERS:=$(addsuffix .cpp, $(addprefix $(GENDIR), $(basename $(PARSERS))))

numwords = $(lastword $(subst /, ,$(1)))
striplib = mkdir $(lastword $(subst /, ,$(1))); cd $(lastword $(subst /, ,$(1))); ar x $(1); cd ..;

ifneq ($(strip $(ADDITIONALLIBS)),)
	MAKELIBS:= mkdir temp; cd temp; $(foreach a, $(ADDITIONALLIBS), $(call striplib, $(a), $(COUNTER))) cd ..;
	CLEANTEMP := rm -rf temp
	EXTRAOBJS := temp/*/*.o
endif

.PHONY: all

all: $(BINDIR)$(TARGET)/lib$(LIB).a

ifneq "$(MAKECMDGOALS)" "clean"
-include $(SOURCES:%.cpp=$(OBJDIR)$(TARGET)/%.d)
-include $(PARSERS:%.y=$(OBJDIR)$(TARGET)/%.g.d)
-include $(LEXERS:%.re=$(OBJDIR)$(TARGET)/%.g.d)
endif

$(BINDIR)$(TARGET)/lib$(LIB).a:$(OBJECTS)
	test -d $(BINDIR) || mkdir $(BINDIR)
	test -d $(BINDIR)$(TARGET) || mkdir $(BINDIR)$(TARGET)
	@$(MAKELIBS)
	ar cq $@ $(OBJECTS) $(EXTRAOBJS) 
	@$(CLEANTEMP)

$(OBJDIR)$(TARGET)/%.o: $(OBJDIR)$(TARGET)/%.d
	@test -d $(OBJDIR) || mkdir $(OBJDIR) 
	@test -d $(OBJDIR)$(TARGET) || mkdir $(OBJDIR)$(TARGET)	
	$(CXX) $(CXXFLAGS) -c $(SOURCEDIR)$*.cpp -o $@ 

$(OBJDIR)$(TARGET)/%.o: $(OBJDIR)$(TARGET)/%.g.d
	@test -d $(OBJDIR) || mkdir $(OBJDIR) 
	@test -d $(OBJDIR)$(TARGET) || mkdir $(OBJDIR)$(TARGET)	
	$(CXX) $(CXXFLAGS) -c $(GENDIR)$*.cpp -o $@ 

$(OBJDIR)$(TARGET)/%.d:$(SOURCEDIR)%.cpp
	@echo Make Depend $(SOURCEDIR)$*.cpp \>\> $(OBJDIR)$(TARGET)/$*.d
	@test -d $(OBJDIR) || mkdir $(OBJDIR) 
	@test -d $(OBJDIR)$(TARGET) || mkdir $(OBJDIR)$(TARGET)	
	@$(CXX) -MM $(CXXFLAGS) -c $(SOURCEDIR)$*.cpp -o $@
	@mv $(OBJDIR)$(TARGET)/$*.d $(OBJDIR)$(TARGET)/$*.d.t
	@sed 's/$*.o/$(SEDDIR)$(TARGET)\/$*.o $(SEDDIR)$(TARGET)\/$*.d/' < $(OBJDIR)$(TARGET)/$*.d.t > $(OBJDIR)$(TARGET)/$*.d
	@rm -f $(SEDDIR)$(TARGET)/$*.d.t

$(OBJDIR)$(TARGET)/%.g.d:$(GENDIR)%.cpp
	@echo Make Generated Depend $(GENDIR)$*.cpp \>\> $(OBJDIR)$(TARGET)/$*.g.d
	@test -d $(OBJDIR) || mkdir $(OBJDIR) 
	@test -d $(OBJDIR)$(TARGET) || mkdir $(OBJDIR)$(TARGET)	
	@$(CXX) -MM $(CXXFLAGS) -c $(GENDIR)$*.cpp -o $@
	@mv $(OBJDIR)$(TARGET)/$*.g.d $(OBJDIR)$(TARGET)/$*.d.t
	@sed 's/$*.o/$(SEDDIR)$(TARGET)\/$*.o $(SEDDIR)$(TARGET)\/$*.g.d/' < $(OBJDIR)$(TARGET)/$*.d.t > $(OBJDIR)$(TARGET)/$*.g.d
	@rm -f $(SEDDIR)$(TARGET)/$*.d.t

$(GENDIR)%.cpp:$(LANGDIR)%.re $(ALLPARSERS)
	@echo Generating lexer from $*.re
	@re2c --no-generation-date -o $(GENDIR)$*.cpp -b $(LANGDIR)$*.re

$(GENDIR)%.cpp:$(LANGDIR)%.y
	@echo Generating parser from $*.y
	@lemon T=$(LANGDIR)lempar.c $(LANGDIR)$*.y
	@mv $(LANGDIR)$*.h $(GENDIR)$*.h
	@mv $(LANGDIR)$*.c $(GENDIR)$*.cpp
	@mv $(LANGDIR)$*.out $(GENDIR)$*.out

clean:
	rm -rf $(OBJDIR)	
	if test -d $(GENDIR); then rm -rf $(GENDIR)*; fi
